App Open
App Open ads are full-screen ads that appear when users launch your app, providing an excellent opportunity to monetize app startup moments. Unlike interstitial ads, App Open ads are specifically designed for app launch scenarios and help create a smooth user experience during cold starts and app foregrounding events.
Key Features
- Launch Optimization: Designed specifically for app startup scenarios
- User-Friendly: Integrates seamlessly with splash screens and loading experiences
- Revenue Maximization: Monetizes high-engagement moments when users actively open your app
- Retention-Focused: Built with user retention best practices in mind
Best Practices
- Always use a splash/loading screen before showing the App Open ad
- Inform users about the upcoming ad with a message like "Watch an ad from our sponsor while the app loads"
- Ensure proper sequence: Splash screen → App Open ad → App content
- Initialize the SDK before loading App Open ads
- Avoid parallel loading of multiple ad formats during app startup
To maintain good user experience and retention:
- Implement external frequency capping outside of the SDK
- Consider cooldown periods between App Open ads
- Wait for new users to engage with your app before showing their first App Open ad
- Show ads strategically (e.g., every 2nd or 3rd app launch)
Start loading an ad
Load App Open ads during SDK initialization, ideally in your main game manager or startup script.
x3mads::XMediatorAds::getInstance()->startWith(
"<your-app-key>",
initSettings,
[](const x3mads::InitResult& result) {
CCLOG("SDK initialized!");
x3mads::XMediatorAds::getInstance()->loadAppOpen("<your-placement-id>");
}
);
Showing an ad
Show App Open ads when your app comes to the foreground. Check if an ad is ready before attempting to show it.
if (x3mads::XMediatorAds::getInstance()->isAppOpenReady("<your-placement-id>")) {
x3mads::XMediatorAds::getInstance()->showAppOpenFromAdSpace("<your-placement-id>", "app-open-ad-space");
}
Built-in features
Auto loading
When App Open ads are dismissed or fail to show, the SDK automatically triggers a new load request to ensure the next app launch opportunity is ready.
Auto retry
Failed load attempts are automatically retried with exponential backoff, ensuring optimal fill rates for your app launch monetization.
Additional settings
Register ad callbacks
Monitor App Open ad lifecycle events to implement custom logic and user experience flows:
// Load Callback
x3mads::XMediatorAds::getInstance()->setAppOpenLoadedCallback([](const std::string& placementId, const x3mads::LoadResult& result) {
CCLOG("AppOpen loaded! placementId: %s", placementId.c_str());
});
// Showed Callback
x3mads::XMediatorAds::getInstance()->setAppOpenShowedCallback([](const std::string& placementId) {
CCLOG("AppOpen is being shown! placementId: %s", placementId.c_str());
// Hide splash screen here
});
// Failed to show callback
x3mads::XMediatorAds::getInstance()->setAppOpenFailedToShowCallback([](const std::string& placementId, const x3mads::AdError& error) {
// If you need to resume your app's flow, make sure to do it here and in the OnDismissed callback
CCLOG("AppOpen failed to show. placementId: %s, Reason: %s", placementId.c_str(), error.getMessage().c_str());
});
// Dismissed callback
x3mads::XMediatorAds::getInstance()->setAppOpenDismissedCallback([](const std::string& placementId) {
// If you need to resume your app's flow, make sure to do it here and in the OnFailedToShow callback
CCLOG("AppOpen dismissed! placementId: %s, Resume gameplay", placementId.c_str());
});
// Impression Callback
x3mads::XMediatorAds::getInstance()->setAppOpenImpressionCallback([](const std::string& placementId, const x3mads::ImpressionData& impressionData) {
CCLOG("AppOpen impression! placementId: %s", placementId.c_str());
});
// Click Callback
x3mads::XMediatorAds::getInstance()->setAppOpenClickedCallback([](const std::string& placementId) {
CCLOG("AppOpen clicked! placementId: %s", placementId.c_str());
});
Cocos2d-x Lifecycle Integration
App Open ads work best when integrated with Cocos2d-x application lifecycle events:
// In your AppDelegate or main scene
void YourScene::onEnterForeground() {
// App gained focus - potential App Open ad opportunity
showAppOpenIfReady();
}
void YourScene::onEnterBackground() {
// App lost focus
}
This ensures your App Open ads are shown at the most appropriate moments when users return to your Cocos2d-x application.
Code example
Implementation example showing App Open ads with splash screen integration:
// AppOpenManager.h
#pragma once
#include "cocos2d.h"
#include "x3mads/XMediatorAds.hpp"
class AppOpenManager : public cocos2d::Node {
public:
static AppOpenManager* create(const std::string& appKey, const std::string& placementId);
bool init(const std::string& appKey, const std::string& placementId);
void showSplashScreen();
void showAppOpenIfReady();
private:
std::string _appKey;
std::string _placementId;
bool _isAppOpenReady;
cocos2d::Node* _splashScreen;
cocos2d::Label* _splashMessage;
cocos2d::ProgressTimer* _loadingBar;
void initializeSDKAndLoadAppOpen();
void loadAppOpen();
void hideSplashScreen();
void proceedToMainGame();
void setupCallbacks();
};
// AppOpenManager.cpp
#include "AppOpenManager.h"
USING_NS_CC;
AppOpenManager* AppOpenManager::create(const std::string& appKey, const std::string& placementId) {
AppOpenManager* ret = new AppOpenManager();
if (ret && ret->init(appKey, placementId)) {
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
bool AppOpenManager::init(const std::string& appKey, const std::string& placementId) {
if (!Node::init()) {
return false;
}
_appKey = appKey;
_placementId = placementId;
_isAppOpenReady = false;
showSplashScreen();
initializeSDKAndLoadAppOpen();
return true;
}
void AppOpenManager::showSplashScreen() {
auto visibleSize = Director::getInstance()->getVisibleSize();
_splashScreen = Node::create();
this->addChild(_splashScreen);
// Background
auto background = LayerColor::create(Color4B::BLACK);
_splashScreen->addChild(background);
// Message
_splashMessage = Label::createWithTTF("Watch an ad from our sponsor while the app loads...", "fonts/arial.ttf", 24);
_splashMessage->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2 + 50));
_splashScreen->addChild(_splashMessage);
// Loading bar
auto loadingBg = Sprite::create("loading_bg.png");
loadingBg->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2 - 50));
_splashScreen->addChild(loadingBg);
_loadingBar = ProgressTimer::create(Sprite::create("loading_fill.png"));
_loadingBar->setType(ProgressTimer::Type::BAR);
_loadingBar->setMidpoint(Vec2(0, 0.5f));
_loadingBar->setBarChangeRate(Vec2(1, 0));
_loadingBar->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2 - 50));
_loadingBar->setPercentage(0);
_splashScreen->addChild(_loadingBar);
}
void AppOpenManager::initializeSDKAndLoadAppOpen() {
x3mads::InitSettings initSettings;
x3mads::XMediatorAds::getInstance()->startWith(
_appKey,
initSettings,
[this](const x3mads::InitResult& result) {
CCLOG("SDK initialized!");
loadAppOpen();
// Simulate loading progress
auto progressAction = ProgressTo::create(2.0f, 100.0f);
auto delayAction = DelayTime::create(1.0f);
auto callbackAction = CallFunc::create([this]() {
showAppOpenIfReady();
});
_loadingBar->runAction(Sequence::create(progressAction, delayAction, callbackAction, nullptr));
}
);
}
void AppOpenManager::loadAppOpen() {
setupCallbacks();
x3mads::XMediatorAds::getInstance()->loadAppOpen(_placementId);
}
void AppOpenManager::setupCallbacks() {
// Load Callback
x3mads::XMediatorAds::getInstance()->setAppOpenLoadedCallback([this](const std::string& placementId, const x3mads::LoadResult& result) {
_isAppOpenReady = true;
CCLOG("AppOpen loaded! placementId: %s", placementId.c_str());
_loadingBar->setPercentage(100);
});
// Showed Callback
x3mads::XMediatorAds::getInstance()->setAppOpenShowedCallback([this](const std::string& placementId) {
CCLOG("AppOpen is being shown! placementId: %s", placementId.c_str());
hideSplashScreen();
});
// Failed to show callback
x3mads::XMediatorAds::getInstance()->setAppOpenFailedToShowCallback([this](const std::string& placementId, const x3mads::AdError& error) {
CCLOG("AppOpen failed to show. placementId: %s, Reason: %s", placementId.c_str(), error.getMessage().c_str());
proceedToMainGame();
});
// Dismissed callback
x3mads::XMediatorAds::getInstance()->setAppOpenDismissedCallback([this](const std::string& placementId) {
CCLOG("AppOpen dismissed! placementId: %s, Resume gameplay", placementId.c_str());
proceedToMainGame();
});
// Impression Callback
x3mads::XMediatorAds::getInstance()->setAppOpenImpressionCallback([this](const std::string& placementId, const x3mads::ImpressionData& impressionData) {
CCLOG("AppOpen impression! placementId: %s", placementId.c_str());
});
// Click Callback
x3mads::XMediatorAds::getInstance()->setAppOpenClickedCallback([this](const std::string& placementId) {
CCLOG("AppOpen clicked! placementId: %s", placementId.c_str());
});
}
void AppOpenManager::showAppOpenIfReady() {
if (x3mads::XMediatorAds::getInstance()->isAppOpenReady(_placementId)) {
x3mads::XMediatorAds::getInstance()->showAppOpenFromAdSpace(_placementId, "app-open-ad-space");
} else {
// No ad ready, proceed to main game
proceedToMainGame();
}
}
void AppOpenManager::hideSplashScreen() {
if (_splashScreen) {
_splashScreen->setVisible(false);
}
}
void AppOpenManager::proceedToMainGame() {
hideSplashScreen();
// Load main game scene or show main menu
// Director::getInstance()->replaceScene(MainGameScene::createScene());
CCLOG("Proceeding to main game content");
}